﻿using System;
using Cfg.Attributes;
using Cfg.Builders;
using Cfg.ConfigProviders;
using Cfg.ConfigValues;
using Cfg.Exceptions;
using Cfg.ValidationAttributes;
using NUnit.Framework;

namespace Cfg.Test
{
    public class Foo
	{
		public static string PropertyWithoutSetter
		{
			get { return "test"; }
		}

	}

	public class InitTest
	{
		[Test]
		public void InitConfigWithPropertiesWithoutSetter()
		{
			AppSettings.Init<Foo>();
		}
	}

    [TestFixture]
	public class ConfigTest
	{
		[SetUp]
		public void Setup()
		{
		    try
		    {
			    AppSettings.Init<TestConfig>();
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
            }
		}

		[Test]
		public void GetIntArray()
		{
			Assert.AreEqual(3, TestConfig.IntArray.Length);
			Assert.AreEqual(1, TestConfig.IntArray[0]);
			Assert.AreEqual(2, TestConfig.IntArray[1]);
			Assert.AreEqual(3, TestConfig.IntArray[2]);
		}

		[Test]
		public void GetNullableIntWithoutValue()
		{
			Assert.AreEqual(null, TestConfig.NullableIntWithoutValue);
		}

        [Test]
        public void GetIntValueWithMaxConstraint()
        {
            var config = new ConfigBuilder(typeof(TestConfig), null, new DotnetConfigFileProvider(null));
            var value = config.GetFieldValue("IntValueWithMaxConstraint");
            Assert.AreEqual(5, value);
        }

        [Test, ExpectedException(typeof(OutOfBoundsException))]
        public void GetIntValueWithMaxConstraintOutOfBounds()
        {
            var attributes = new object[] {new MaxAttribute(10)};

            var vb = new ValueBuilder(typeof (int), attributes, null, "50", "50");
            vb.GetValue();
        }

		[Test]
		public void GetNullableInt()
		{
			Assert.AreEqual(1, TestConfig.NullableIntWithValue);
		}

		[Test]
		public void GetLongValueThatDoesNotExistInConfigFile()
		{
			Assert.AreEqual(0, TestConfig.LongValueThatDoesNotExistInConfigfile);
		}

		[Test]
		public void GetLongValue()
		{
			Assert.AreEqual(12345678901, TestConfig.LongValue);
		}

		[Test]
		public void GetIntValueThatDoesNotExistInConfigFile()
		{
			Assert.AreEqual(0, TestConfig.IntValueThatDoesNotExistInConfigfile);
		}

		[Test]
		public void GetIntValue()
		{
			Assert.AreEqual(5, TestConfig.IntValue);
		}

		[Test, ExpectedException(typeof(InvalidFormatException))]
		public void GetIntValueOutOfBounds()
		{
		    var vb = new ValueBuilder(typeof (int), "999999999999999999999999");
		    vb.GetValue();
		}

		[Test]
		public void GetStringArray()
		{
			Assert.AreEqual(4, TestConfig.StringArray.Length);
			Assert.AreEqual("a", TestConfig.StringArray[0]);
			Assert.AreEqual("b", TestConfig.StringArray[1]);
			Assert.AreEqual("c", TestConfig.StringArray[2]);
			Assert.AreEqual("d", TestConfig.StringArray[3]);
		}

		[Test]
		public void GetStringArrayThatDoesNotExistInConfig()
		{
            var config = new ConfigBuilder(typeof(TestConfig), null, new DotnetConfigFileProvider(null));
			var value = config.GetFieldValue("StringArrayThatDoesNotExistInConfig");
			Assert.AreEqual(null, value);
		}

		[Test]
		public void GetStringValue()
		{
			Assert.AreEqual("test", TestConfig.StringValue);
		}

		[Test]
		public void GetStringValueThatDoesNotExistInConfigFile()
		{
            var config = new ConfigBuilder(typeof(TestConfig), null, new DotnetConfigFileProvider(null));
            var value = config.GetFieldValue("StringValueThatDoesNotExistInConfigFile");
            Assert.AreEqual(null, value);
        }

        [Test, ExpectedException(typeof(ValueNotFoundException))]
        public void GetRequiredStringValueFromConfig()
        {
            var attr = new object[] {new RequiredAttribute()};
            var vb = new ValueBuilder(typeof (int), attr, null, null, null);
            vb.GetValue();
        }

        [Test]
        public void GetRequiredStringValueWithDefaultValue()
        {
            var config = new ConfigBuilder(typeof(TestConfig), null, new DotnetConfigFileProvider(null));
            var value = config.GetFieldValue("RequiredFieldwithDefaultValue");
            Assert.AreEqual("default", value);
        }
	}
}
